<template>
  <base-option :selected="selected" :field-config="fieldConfig" :form-config="formConfig">
    <template #advanced>
      <el-card style="font-size: 12px" shadow="never">
        <template #header>
          <div style="display: flex; justify-content: space-between">
            <span>公共变量</span>
            <el-button style="margin-left: 24px" type="primary" link @click="addVars"> 添加 </el-button>
          </div>
        </template>
        <el-scrollbar height="260px">
          <el-tree style="max-width: 300px" :data="treeData" empty-text="无数据" @node-click="handleNodeClick">
            <template #default="{ node, data }">
              <div style="flex: 1; display: flex; justify-content: space-between; font-size: 12px">
                <span>{{ node.label }}</span>

                <div>
                  <span style="color: #a8abb2">{{ data.type }}</span>
                  <el-button style="margin-left: 20px" type="primary" link @click="edit(node, data)"> 编辑 </el-button>
                  <el-button
                    style="margin-left: 10px"
                    type="danger"
                    link
                    :disabled="data.deleted"
                    @click="remove(node, data)"
                  >
                    移除
                  </el-button>
                </div>
              </div>
            </template>
          </el-tree>
        </el-scrollbar>
        <template #footer>
          <el-scrollbar max-height="350px">
            <div style="color: #909090">
              {{ selectedValue }}
            </div>
          </el-scrollbar>
        </template>
      </el-card>
    </template>
  </base-option>
  <el-dialog
    v-model="dialogCode"
    title="公共变量设置"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    destroy-on-close
  >
    <div style="display: flex; align-items: center; margin-bottom: 10px">
      <span>变量名称</span>
      <el-input v-model="variableName" :disabled="isEdit" size="default" style="width: 240px; margin-left: 10px" />
    </div>

    <code-editor v-model="variableCode" mode="javascript" :user-worker="false" />

    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="handleSave">确定</el-button>
        <el-button @click="dialogCode = false">关闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, toRefs, computed, getCurrentInstance } from 'vue'
import baseOption from './base-option.vue'
import propsDefinition from './props'
const props = defineProps(propsDefinition)
const { selected, fieldConfig, formConfig, widgetList } = toRefs(props)
const { proxy } = getCurrentInstance()

const dialogCode = ref(false)
const variableCode = ref('')
const variableName = ref('')
const isEdit = ref(false)

/**
 * 初始化内置变量
 */
const initVars = computed(() => {
  if (widgetList.value.find((x) => x.type === 'card' && x.options.name === 'leave')) {
    return [
      '早餐时段',
      '午餐时段',
      '晚餐时段',
      '早餐价格',
      '午餐价格',
      '晚餐价格',
      '是否为工作日',
      '应退早餐',
      '应退午餐',
      '应退晚餐'
    ]
  }
  return []
})

// Object对象类型转tree数据
function objToTree(obj) {
  return Object.entries(obj).map(([key, value]) => {
    let type = 'Object'
    if (Array.isArray(value)) {
      type = 'Array'
    } else if (typeof value === 'number') {
      type = 'Number'
    } else if (typeof value === 'function') {
      type = 'Function'
    } else if (isFunctionString(value)) {
      type = 'Function'
    } else {
      type = 'String'
    }
    return {
      label: key,
      value: value,
      type: type,
      deleted: initVars.value.includes(key) // 是否为内置变量，内置变量不允许删除
    }
  })
}

// 尝试创建函数
function isFunctionString(str) {
  try {
    new Function(str)
    return true
  } catch (e) {
    return false
  }
}

const treeData = computed(() => {
  if (!selected.value.options.publicVars) return []
  return objToTree(selected.value.options.publicVars)
})

const selectedValue = ref('')
const handleNodeClick = (data) => {
  selectedValue.value = selected.value.options.publicVars[data.label]
}
const remove = (node, data) => {
  if (selected.value && selected.value.options.publicVars && data && data.label) {
    delete selected.value.options.publicVars[data.label]
  }
}
const edit = (node, data) => {
  if (typeof data.value === 'string' && isFunctionString(data.value)) {
    variableCode.value = data.value
  } else {
    variableCode.value = JSON.stringify(data.value)
  }
  variableName.value = data.label
  isEdit.value = true
  dialogCode.value = true
}
const addVars = () => {
  variableName.value = '新建变量'
  variableCode.value = '这里输入变量的值，可以是字符串、数字、数组、对象，甚至是函数'
  isEdit.value = false
  dialogCode.value = true
}

const handleSave = () => {
  // 判断变量名称是否为空
  if (!variableName.value || variableName.value.trim() === '') {
    proxy.$message.error('变量名称不能为空.')
    return
  }
  // 判断变量名称是否重复
  if (
    !isEdit.value &&
    selected.value.options.publicVars &&
    selected.value.options.publicVars[variableName.value.trim()]
  ) {
    proxy.$message.error('变量名称已存在，请更换一个.')
    return
  }
  try {
    selected.value.options.publicVars[variableName.value.trim()] = JSON.parse(variableCode.value)
  } catch (e) {
    selected.value.options.publicVars[variableName.value.trim()] = variableCode.value
  }

  // console.log('selected.value.options.publicVars :>> ', selected.value.options.publicVars)
  dialogCode.value = false
}
</script>
